from datetime import datetime

from sqlalchemy import and_
import math
import numpy as np
from typing import Dict, List

from app.database import convert
from app.exts import ironman_redis as redis
from app.models.po.lugang.lugang_qinshi_po import lugang_qinshi_column
from app.models.po.lugang.lugang_original_po import LuGangActivinessPredictPO, LuGangActivinessDataPO
from app.services.models.lugang_activiness_long_model import lugang_activiness_long


def dump_lugang_activeness_long():
    """
    炉缸活跃性预测
    :return:
    """
    long_value_dict = redis.hget_all_str_decode("lugang_activiness_long")
    long_time_dict = redis.hget_all_str_decode("lugang_activiness_long_update")

    for key, value in long_value_dict.items():
        date_time_str = long_time_dict.get(key)
        now = datetime.now()
        date_time = datetime.strptime(date_time_str, "%Y-%m-%d %H:%M:%S")

        min_record = convert.query(LuGangActivinessDataPO,
                                   LuGangActivinessDataPO.name == key,
                                   LuGangActivinessDataPO.date_time == date_time,
                                   LuGangActivinessDataPO.type == 'longTerm',
                                   LuGangActivinessDataPO.level == 'min').first()

        if min_record is None:
            record: LuGangActivinessDataPO = LuGangActivinessDataPO()
            record.level = "min"
            record.type = "longTerm"
            record.name = key
            record.value = value
            record.date_time = date_time
            record.gmt_create = now
            record.gmt_modified = now
            convert.add_one(record)

        day_start = datetime(now.year, now.month, now.day, 0, 0, 0)
        day_end = datetime(now.year, now.month, now.day, 23, 59, 59)

        histories = convert.query(LuGangActivinessDataPO,
                                  LuGangActivinessDataPO.name == key,
                                  LuGangActivinessDataPO.date_time >= day_start,
                                  LuGangActivinessDataPO.date_time <= day_end,
                                  LuGangActivinessDataPO.type == 'longTerm',
                                  LuGangActivinessDataPO.level == 'min').all()

        if len(histories) > 0:
            day_record = convert.query(LuGangActivinessDataPO,
                                       LuGangActivinessDataPO.name == key,
                                       LuGangActivinessDataPO.date_time == day_end,
                                       LuGangActivinessDataPO.type == 'longTerm',
                                       LuGangActivinessDataPO.level == 'day').first()
            avg = sum([h.value for h in histories]) / len(histories)
            if day_record is None:
                day_record: LuGangActivinessDataPO = LuGangActivinessDataPO()
                day_record.level = "day"
                day_record.type = "longTerm"
                day_record.name = key
                day_record.value = avg
                day_record.date_time = day_end
                day_record.gmt_create = now
                day_record.gmt_modified = now
                convert.add_one(day_record)
            else:
                convert.update_model(day_record, dict(value=avg, gmt_modified=datetime.now()))


def dump_lugang_activeness_predict_long():
    now = datetime.now()
    day_end = datetime(now.year, now.month, now.day, 23, 59, 59)

    histories: List[LuGangActivinessDataPO] = convert.query(LuGangActivinessDataPO,
                                                            LuGangActivinessDataPO.date_time == day_end,
                                                            LuGangActivinessDataPO.type == 'longTerm',
                                                            LuGangActivinessDataPO.level == 'day').all()

    a = [history.value for history in histories if history.name in
         ['CG_LT_GL_GL04_LDWDBG6200TE1134', 'CG_LT_GL_GL04_LDWDBG6200TE1137', 'CG_LT_GL_GL04_LDWDBG6200TE1140',
          'CG_LT_GL_GL04_LDWDBG6200TE1144', 'CG_LT_GL_GL04_LDWDBG5700TE1109', 'CG_LT_GL_GL04_LDWDBG5700TE1112',
          'CG_LT_GL_GL04_LDWDBG5700TE1115', 'CG_LT_GL_GL04_LDWDBG5700TE1119']]

    if len(a) < 8:
        return

    numerator = sum(a) / len(a)

    b = [history.value for history in histories if history.name in
         ['CG_LT_GL_GL04_LGWDBG10500TE1247', 'CG_LT_GL_GL04_LGWDBG11500TE1249', 'CG_LT_GL_GL04_LGWDBG11500TE1251',
          'CG_LT_GL_GL04_LGWDBG10500TE1245', 'CG_LT_GL_GL04_LGWDBG11500TE1255', 'CG_LT_GL_GL04_LGWDBG9500TE1235',
          'CG_LT_GL_GL04_LGWDBG10500TE1237', 'CG_LT_GL_GL04_LGWDBG10500TE1241', 'CG_LT_GL_GL04_LGWDBG9500TE1233',
          'CG_LT_GL_GL04_LGWDBG10500TE1243', 'CG_LT_GL_GL04_LGWDBG8500TE1223', 'CG_LT_GL_GL04_LGWDBG9500TE1225',
          'CG_LT_GL_GL04_LGWDBG9500TE1229', 'CG_LT_GL_GL04_LGWDBG9500TE1227', 'CG_LT_GL_GL04_LGWDBG8500TE1221',
          'CG_LT_GL_GL04_LGWDBG9500TE1231', 'CG_LT_GL_GL04_LGWDBG8000TE1207', 'CG_LT_GL_GL04_LGWDBG8000TE1205',
          'CG_LT_GL_GL04_LGWDBG8500TE1211', 'CG_LT_GL_GL04_LGWDBG8500TE1209', 'CG_LT_GL_GL04_LGWDBG8500TE1217',
          'CG_LT_GL_GL04_LGWDBG8500TE1213', 'CG_LT_GL_GL04_LGWDBG8500TE1219', 'CG_LT_GL_GL04_LGWDBG7500TE1191',
          'CG_LT_GL_GL04_LGWDBG7500TE1190', 'CG_LT_GL_GL04_LGWDBG8000TE1195', 'CG_LT_GL_GL04_LGWDBG8000TE1193',
          'CG_LT_GL_GL04_LGWDBG8000TE1199', 'CG_LT_GL_GL04_LGWDBG8000TE1201', 'CG_LT_GL_GL04_LGWDBG8000TE1203',
          'CG_LT_GL_GL04_LGWDBG7000TE1175', 'CG_LT_GL_GL04_LGWDBG7000TE1173', 'CG_LT_GL_GL04_LGWDBG7500TE1179',
          'CG_LT_GL_GL04_LGWDBG7500TE1177', 'CG_LT_GL_GL04_LGWDBG7500TE1185', 'CG_LT_GL_GL04_LGWDBG7500TE1181',
          'CG_LT_GL_GL04_LGWDBG7500TE1187', 'CG_LT_GL_GL04_LGWDBG7000TE1161', 'CG_LT_GL_GL04_LDWDBG6500TE1159',
          'CG_LT_GL_GL04_LGWDBG7000TE1165', 'CG_LT_GL_GL04_LGWDBG7000TE1163', 'CG_LT_GL_GL04_LGWDBG7000TE1169',
          'CG_LT_GL_GL04_LGWDBG7000TE1167', 'CG_LT_GL_GL04_LDWDBG6500TE1157', 'CG_LT_GL_GL04_LGWDBG7000TE1171']]

    if len(b) <= 0:
        return

    denominator = sum(b) / len(b)

    y = numerator / denominator

    model_input = get_model_input(histories,
                                  ['CG_LT_GL_GL04_LGWDBG8000TE1207', 'CG_LT_GL_GL04_LGWDBG9500TE1233',
                                   'CG_LT_GL_GL04_LGWDBG9500TE1234', 'CG_LT_GL_GL04_LJWDBG4000TE1101',
                                   'CG_LT_GL_GL04_LGWDBG10500TE1246', 'CG_LT_GL_GL04_LGWDBG6500TE1159',
                                   'CG_LT_GL_GL04_LDWDBG6200TE1135'])

    predict = lugang_activiness_long.process(model_input)

    day_record = convert.query(LuGangActivinessPredictPO,
                               LuGangActivinessPredictPO.date_time == day_end,
                               LuGangActivinessPredictPO.type == 'longTerm',
                               LuGangActivinessPredictPO.level == 'day').first()

    if day_record is None:
        day_record = LuGangActivinessPredictPO()
        day_record.date_time = day_end
        day_record.current = y
        day_record.predict = predict
        day_record.type = 'longTerm'
        day_record.level = 'day'
        day_record.gmt_create = now
        day_record.gmt_create = now
        convert.add_one(day_record)
    else:
        convert.update_model(day_record, dict(current=y, predict=predict, gmt_modified=datetime.now()))


def get_model_input(datas: List[LuGangActivinessDataPO], columns):
    data_dict = {data.name: data.value for data in datas}

    return {column: data_dict.get(column, 0) for column in columns}
